﻿//-----------------------------------------------------------------------
// <Copyright>
// * Copyright (C) 2022 RuYiAdmin All Rights Reserved
// </Copyright>
//-----------------------------------------------------------------------

using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RuYiAdmin.Net.CommonInfrastructure.Classes;
using RuYiAdmin.Net.CommonInfrastructure.Enums.Business;
using RuYiAdmin.Net.CommonInfrastructure.Enums.Framework;
using RuYiAdmin.Net.CommonInfrastructure.Models;
using RuYiAdmin.Net.CommonInfrastructure.Utilities.Utils;
using RuYiAdmin.Net.EntityDataModel.DataTransformationModel.SystemModel;
using RuYiAdmin.Net.EntityDataModel.EntityModel.SystemModel;
using RuYiAdmin.Net.ServiceLayer.BusinessService.Interface.FrameworkInterface;
using RuYiAdmin.Net.ServiceLayer.BusinessService.Interface.SystemInterface;
using RuYiAdmin.Net.WebApi.RuYiAdminCode.RuYiAdminAnnotation;
using RuYiAdmin.Net.WebApi.RuYiAdminCode.RuYiAdminBase;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace RuYiAdmin.Net.WebApi.RuYiAdminController.SystemController
{
    /// <summary>
    /// 通知公告管理控制器
    /// </summary>
    public class SysAnnouncementManagementController : RuYiAdminBaseController<SysAnnouncement>
    {
        #region 属性及构造函数

        /// <summary>
        /// 通知公告业务接口实例
        /// </summary>
        private readonly ISysAnnouncementService AnnouncementService;

        /// <summary>
        /// AutoMapper实例
        /// </summary>
        private readonly IMapper AutoMapper;

        /// <summary>
        /// 收件人服务层接口实例
        /// </summary>
        private readonly ISysAddresseeService AddresseeService;

        /// <summary>
        /// 系统用户服务层接口实例
        /// </summary>
        private readonly ISysUserService UserService;

        /// <summary>
        /// 系统附件服务层接口实例
        /// </summary>
        private readonly ISysAttachmentService AttachmentService;

        /// <summary>
        /// MQ接口实例
        /// </summary>
        private readonly IMQService MQService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="AnnouncementService"></param>
        /// <param name="AutoMapper"></param>
        /// <param name="AddresseeService"></param>
        /// <param name="UserService"></param>
        /// <param name="AttachmentService"></param>
        /// <param name="MQService"></param>
        public SysAnnouncementManagementController(ISysAnnouncementService AnnouncementService,
                                                IMapper AutoMapper,
                                                ISysAddresseeService AddresseeService,
                                                ISysUserService UserService,
                                                ISysAttachmentService AttachmentService,
                                                IMQService MQService) : base(AnnouncementService)
        {
            this.AnnouncementService = AnnouncementService;
            this.AutoMapper = AutoMapper;
            this.AddresseeService = AddresseeService;
            this.UserService = UserService;
            this.AttachmentService = AttachmentService;
            this.MQService = MQService;
        }

        #endregion

        #region 查询通知公告列表

        /// <summary>
        /// 查询通知公告列表
        /// </summary>
        /// <param name="searchCondition">查询条件</param>
        /// <returns>ActionResponseResult</returns>
        [HttpPost]
        [Log(OperationType.QueryList)]
        [Permission("announcement:query:list")]
        public async Task<IActionResult> Post(SearchCondition searchCondition)
        {
            var actionResponseResult = await this.AnnouncementService.SqlQueryAsync(searchCondition, "sqls:sql:query_sysannouncement");
            return Ok(actionResponseResult);
        }

        #endregion

        #region 按编号获取通知公告

        /// <summary>
        /// 按编号获取通知公告
        /// </summary>
        /// <param name="id">通知公告编号</param>
        /// <returns>ActionResponseResult</returns>
        [HttpGet("{id}")]
        [Log(OperationType.QueryEntity)]
        [Permission("announcement:query:list,sys:announcement:query:list,notification:query:list")]
        public async Task<IActionResult> GetById(Guid id)
        {
            var actionResponseResult = await this.AnnouncementService.GetByIdAsync(id);
            return Ok(actionResponseResult);
        }

        #endregion

        #region 添加通知公告

        /// <summary>
        /// 添加通知公告
        /// </summary>
        /// <param name="announcementDTO">通知公告</param>
        /// <returns>ActionResponseResult</returns>
        [HttpPost]
        [Log(OperationType.AddEntity)]
        [Permission("announcement:add:entity")]
        public async Task<IActionResult> Add([FromBody] SysAnnouncementDTO announcementDTO)
        {
            //数据转化
            var announcement = this.AutoMapper.Map<SysAnnouncement>(announcementDTO);
            //保存数据
            var actionResponseResult = await this.AnnouncementService.AddAsync(announcement);
            //保存通知收件人并发送邮件
            await SengMailAndMessageAsync(announcementDTO);

            return Ok(actionResponseResult);
        }

        #endregion

        #region 编辑通知公告

        /// <summary>
        /// 编辑通知公告
        /// </summary>
        /// <param name="announcementDTO">通知公告</param>
        /// <returns>ActionResponseResult</returns>
        [HttpPut]
        [Log(OperationType.EditEntity)]
        [Permission("announcement:edit:entity")]
        public async Task<IActionResult> Edit([FromBody] SysAnnouncementDTO announcementDTO)
        {
            var announcement = this.AutoMapper.Map<SysAnnouncement>(announcementDTO);
            var actionResponseResult = await this.AnnouncementService.UpdateAsync(announcement);

            #region 删除收件人

            var searchCondition = new SearchCondition();
            searchCondition.SearchItems = new List<SearchItem>();
            searchCondition.SearchItems.Add(new SearchItem()
            {
                Field = "BusinessId",
                SearchMethod = SearchMethod.Equal,
                DataType = DataType.Guid,
                Value = announcement.Id
            });
            var list = this.AddresseeService.GetList(searchCondition).List;
            foreach (var addressee in list)
            {
                actionResponseResult = await this.AddresseeService.DeleteAsync(addressee.Id);
            }

            #endregion

            //保存通知收件人并发送邮件
            await SengMailAndMessageAsync(announcementDTO);

            return Ok(actionResponseResult);
        }

        #endregion

        #region 批量删除通知公告

        /// <summary>
        /// 批量删除通知公告
        /// </summary>
        /// <param name="ids">数组串</param>
        /// <returns>ActionResponseResult</returns>
        [HttpDelete("{ids}")]
        [Log(OperationType.DeleteEntity)]
        [Permission("announcement:del:entities")]
        public async Task<IActionResult> Delete(string ids)
        {
            var array = RuYiStringUtil.GetGuids(ids);

            //批量删除通知公告
            var actionResponseResult = await this.AnnouncementService.DeleteRangeAsync(array);

            foreach (var item in array)
            {
                var searchCondition = new SearchCondition();
                searchCondition.SearchItems = new List<SearchItem>();
                searchCondition.SearchItems.Add(new SearchItem()
                {
                    Field = "BusinessId",
                    SearchMethod = SearchMethod.Equal,
                    DataType = DataType.Guid,
                    Value = item
                });
                var list = this.AddresseeService.GetList(searchCondition).List;
                foreach (var addressee in list)
                {
                    //删除收件人
                    actionResponseResult = await this.AddresseeService.DeleteAsync(addressee.Id);
                }
            }

            return Ok(actionResponseResult);
        }

        #endregion

        #region 获取通知公告收件人

        /// <summary>
        /// 获取通知公告收件人
        /// </summary>
        /// <param name="id">通知公告编号</param>
        /// <returns>ActionResponseResult</returns>
        [HttpGet("{id}")]
        [Log(OperationType.QueryList)]
        [Permission("announcement:edit:entity")]
        public async Task<IActionResult> GetAnnouncementAddressee(Guid id)
        {
            var searchCondition = new SearchCondition();
            searchCondition.SearchItems = new List<SearchItem>();
            searchCondition.SearchItems.Add(new SearchItem()
            {
                Field = "BusinessId",
                SearchMethod = SearchMethod.Equal,
                DataType = DataType.Guid,
                Value = id
            });

            var actionResponseResult = await this.AddresseeService.GetListAsync(searchCondition);
            return Ok(actionResponseResult);
        }

        #endregion

        #region 查询公告列表

        /// <summary>
        /// 查询公告列表
        /// </summary>
        /// <param name="searchCondition">查询条件</param>
        /// <returns>ActionResponseResult</returns>
        [HttpPost]
        [Log(OperationType.QueryList)]
        [Permission("sys:announcement:query:list")]
        public async Task<IActionResult> GetAnnouncements(SearchCondition searchCondition)
        {
            var actionResponseResult = await this.AnnouncementService.SqlQueryAsync(searchCondition, "sqls:sql:query_sys_announcement");
            return Ok(actionResponseResult);
        }

        #endregion

        #region 查询通知列表

        /// <summary>
        /// 查询通知列表
        /// </summary>
        /// <param name="searchCondition">查询条件</param>
        /// <returns>ActionResponseResult</returns>
        [HttpPost]
        [Log(OperationType.QueryList)]
        [Permission("notification:query:list")]
        public async Task<IActionResult> GetNotifications(SearchCondition searchCondition)
        {
            var actionResponseResult = await this.AnnouncementService.QueryNotifications(searchCondition, "sqls:sql:query_sys_notification");
            return Ok(actionResponseResult);
        }

        #endregion

        #region 更改通知收件人阅读状态

        /// <summary>
        /// 更改通知收件人阅读状态
        /// </summary>
        /// <param name="notificationId">通知编号</param>
        /// <returns>ActionResponseResult</returns>
        [HttpGet("{notificationId}")]
        [Log(OperationType.EditEntity)]
        [Permission("notification:query:list")]
        public async Task<IActionResult> UpdateNotificationStatus(Guid notificationId)
        {
            var actionResponseResult = await this.AddresseeService.UpdateNotificationStatus(notificationId);
            return Ok(actionResponseResult);
        }

        #endregion

        #region 发送邮件与及时消息

        private async Task SengMailAndMessageAsync(SysAnnouncementDTO announcementDTO)
        {
            if (announcementDTO.Type == 0 && announcementDTO.Status == 0)
            {
                #region 发送及时消息

                var msg = new SystemMessage();
                msg.Message = "Announcement";
                msg.MessageType = MessageType.Announcement;
                msg.Object = new { announcementDTO.Title };

                this.MQService.SendTopic(JsonConvert.SerializeObject(msg));

                #endregion
            }
            else if (announcementDTO.Type == 1 && !string.IsNullOrEmpty(announcementDTO.Addressee))
            {
                #region 发送邮件与及时消息

                var array = RuYiStringUtil.GetGuids(announcementDTO.Addressee);

                var addressee = new List<SysAddressee>();
                foreach (var item in array)
                {
                    var addr = new SysAddressee();
                    addr.BusinessId = announcementDTO.Id;
                    addr.UserId = item;
                    addr.Status = 0;
                    addressee.Add(addr);
                }
                await this.AddresseeService.AddListAsync(addressee);

                //发送邮件
                if (announcementDTO.SendMail && announcementDTO.Status == 0 && addressee.Count > 0)
                {
                    foreach (var item in array)
                    {
                        var user = this.UserService.GetById(item).Object as SysUser;
                        if (!string.IsNullOrEmpty(user.Email))
                        {
                            //获取附件列表
                            var attachments = this.AttachmentService.GetList().Object as List<SysAttachment>;
                            attachments = attachments.FindAll(t => t.BusinessId == announcementDTO.Id && t.IsDel == (int)DeletionType.Undeleted);

                            //加载附件信息
                            List<FileInfo> files = new List<FileInfo>();
                            foreach (var att in attachments)
                            {
                                files.Add(new FileInfo(att.FilePath));
                            }

                            //发送邮件
                            RuYiMailUtil.SendMail(announcementDTO.Title, announcementDTO.Content, user.Email, files, true);

                            #region 发送及时消息

                            var msg = new SystemMessage();
                            msg.Message = "Notification";
                            msg.MessageType = MessageType.Notification;
                            msg.Object = new { user.Id, announcementDTO.Title };

                            this.MQService.SendTopic(JsonConvert.SerializeObject(msg));

                            #endregion
                        }
                    }
                }

                #endregion
            }
        }

        #endregion
    }
}
